import os

from utils import date_util, k_util, ave_util, excel_util, json_util, macd_util, read_config

today_str = date_util.get_format_date_str("%Y-%m-%d")
result_path = os.path.join(read_config.data_path, 'result', '突破均线', today_str, '历史验证')
result_file_name = '验证结果'
view_file_path = os.path.join(result_path, '验证')

if not os.path.exists(view_file_path):
    os.makedirs(view_file_path)  # 没有创建文件夹


# list_s : 股票列表
# size : 要验证的股票交易日天数
def monitor_up_down(list_s, size):
    # 循环要监控的列表
    for stock_info in list_s:
        code = stock_info['code']  # 股票编码
        name = stock_info['name']  # 股票名称
        monitor_stock(code, name, size)  # 验证股票


# 验证当前股票历史
def monitor_stock(code, name, size):
    capital_pool = 1000000  # 百万的初始资金
    position_money = 0  # 持仓金额
    hand_num = 0  # 持有多少手股票
    k_lines = k_util.day_k_local(code, size + 10)  # 获取比size多五日的k线数据 k_util 可以在代码中获取
    k_lines.reverse()
    size = len(k_lines)  # 重新定义size防止新股票不够用
    k_lines_five = k_lines[5:10]  # 五日K线列表
    k_lines_ten = k_lines[0:10]  # 十日K线列表
    pointer5 = 0  # 5日均线k_lines_five替换指针
    pointer10 = 0  # 10日均线k_lines_ten替换指针
    ave_five = ave_util.ave_line_price(k_lines_five, 5)
    ave_ten = ave_util.ave_line_price(k_lines_ten, 10)
    sp4 = float(json_util.info_to_json(k_lines_five[4])['sp'])
    flag5 = 1  # 1:监控突破 -1:监控跌破 初始化
    flag10 = 1  # 1:监控突破 -1:监控跌破 初始化
    if sp4 > ave_five: flag5 = -1
    if sp4 > ave_ten: flag10 = -1
    # 生成的excel标题行
    content_arr = [['编码', '名称', '日期', '成交价', '买卖', '持有股', '持仓资金', '总资本', 'macd', '间隔天数']]
    common_data = {'code': code, 'name': name, 'capital': capital_pool, 'position': position_money, 'hand': hand_num,
                   'flag5': flag5, 'flag10': flag10, 'trigger_num': 0, 'content': content_arr}
    for num in range(size - 10):
        ave_five = ave_util.ave_line_price(k_lines_five, 5)  # 五日均线价格
        ave_ten = ave_util.ave_line_price(k_lines_ten, 10)  # 十日均线价格
        current_k = json_util.info_to_json(k_lines[num + 10])  # 对比日k线
        k_lines_five[pointer5] = current_k  # 用当日替换最老的一天的k线
        k_lines_ten[pointer10] = current_k  # 用当日替换最老的一天的k线
        pointer5 = (pointer5 + 1) % 5  # 更新替换指针
        pointer10 = (pointer10 + 1) % 10  # 更新替换指针
        current_rq = current_k['rq']  # 次日的日期yyyy-MM-dd
        macd_list = macd_util.get_macd_interval(code, current_rq, 3)  # 获取最近三天的 macd 信息
        macd_form = macd_util.macd_form(macd_list)  # 判断 macd 形态
        common_data['max'] = float(current_k['max'])  # 对比日的最高价
        common_data['min'] = float(current_k['min'])  # 对比日的最低价
        common_data['kp'] = float(current_k['kp'])  # 对比日的开盘价
        common_data['sp'] = float(current_k['sp'])  # 对比日的开盘价
        common_data['rq'] = current_rq  # 对比日日期yyyy-MM-dd
        common_data['macd'] = macd_form  # macd 形态
        common_data['ave5'] = ave_five  # 五日均线价格
        common_data['ave10'] = ave_ten  # 十日均线价格
        common_data = deal_trigger(common_data)  # 处理触发的情况
    if len(common_data['content']) > 1:
        common_data = deal_excel_result(common_data)
        excel_util.gen_an_excel(view_file_path, name + '-' + code, '', common_data['content'])


# 完成交易
def deal_complete(data):
    deal_price = data['deal_price']
    deal_flag = data['deal_flag']
    capital = data['capital']
    hand = data['hand']
    trigger_num = data['trigger_num']
    # buy_sell_flag = 0  # 1买入 2卖出
    # 交易标志 deal_flag = 0  # 1:全仓 2:加半仓 3:清仓 4:减半仓
    if deal_flag == 1 or deal_flag == 2:  # 买入
        buy_sell_flag = 1
        deal_capital = capital
        if hand == 0 and deal_flag == 2:
            deal_capital = int(capital / 2)
        deal_hand = int(deal_capital / (deal_price * 100))
        if deal_hand == 0:  # 如果可购买数量为0 返回结果
            return data
    elif deal_flag == 3 or deal_flag == 4:  # 卖出
        buy_sell_flag = -1
        if hand != 0:
            deal_hand = int(capital / (deal_price * 100))
            if deal_hand == 0 and deal_flag == 4:  # 全仓状态
                deal_hand = int(hand / 2)
            else:  # 清仓
                deal_hand = hand
        else:
            return data
    else:
        return data
    hand = hand + deal_hand * buy_sell_flag
    deal_amt = round(deal_hand * deal_price * 100, 2)  # 成交金额
    deal_tax = round(deal_amt * 0.00025, 2)  # 印花税
    data['bs'] = buy_sell_flag
    data['hand'] = hand
    data['position'] = hand * data['sp'] * 100
    data['capital'] = capital - deal_amt * buy_sell_flag - deal_tax
    data['trigger_num'] = trigger_num + 1
    data = trans_excel_format(data)  # 处理excel格式化
    return data


# 格式化成excel数据
def trans_excel_format(data):
    rq = data['rq']
    content = data['content']
    # content_arr = [['编码', '名称', '日期', '成交价', '买卖', '持有股', '持仓资金', '总资本', 'macd', '间隔天数']]
    # 距离上次交易间隔天数
    interval_days = 0
    if len(content) != 1:
        interval_days = date_util.diff_days_str(content[len(content) - 1][2], rq)
    row = [data['code'], data['name'], rq, data['deal_price'], data['bs'], data['hand'], data['position'],
           data['capital'] + data['position'], data['macd'], interval_days]
    data['content'].append(row)
    return data


# 汇总操作结果
def deal_excel_result(data):
    content = data['content']
    size = len(content)
    content_beg = content[1]
    content_end = content[size - 1]
    end_price = content_end[3]
    beg_price = content_beg[3]
    end_capital = content_end[7]
    beg_date = content_beg[2]
    end_date = content_end[2]
    days = date_util.diff_days_str(content_beg[2], content_end[2])  # 总操作天数
    amt_incr = round((end_price - beg_price) / beg_price * 100, 2)  # 价格涨幅( %)    91.56
    earnings_incr = round((end_capital - 1000000) / 10000, 2)  # 盈利涨幅( %)    91.56
    days_hold_all = 0  # 持仓天数
    days_hold_all_flag = 0  # 持仓天数
    days_empty = 0
    days_empty_flag = 0
    for i in range(1, size):
        row = content[i]
        price = row[3]
        bs = row[4]
        hand = row[5]
        half = row[6]
        all = row[7]
        if days_empty_flag == 1:
            days_empty += row[9]
            days_empty_flag = 0
        if days_hold_all_flag == 1:
            days_hold_all += row[9]
            days_hold_all_flag = 0
        if bs == -1 and hand == 0:
            days_empty_flag = 1
        if bs == 1 and (all - half) / price / 100 < hand / 4:
            days_hold_all_flag = 1
    content.append([])
    content.append(['', '', '', '名称', data['name']])
    content.append(['', '', '', '总操作天数', days])
    content.append(['', '', '', '开始日期', beg_date])
    content.append(['', '', '', '结束日期', end_date])
    content.append(['', '', '', '全仓天数', days_hold_all])
    content.append(['', '', '', '半仓天数', days - days_empty - days_hold_all])
    content.append(['', '', '', '空仓天数', days_empty])
    content.append(['', '', '', '价格涨幅( %)', amt_incr])
    content.append(['', '', '', '盈利涨幅( %)', earnings_incr])
    content.append(['', '', '', '操作次数', size - 1])
    return data


# 处理触发的情况
def deal_trigger(data):
    name = data['name']
    ave5 = data['ave5']
    max = data['max']
    min = data['min']
    kp = data['kp']
    macd = data['macd']
    ave10 = data['ave10']
    flag5 = data['flag5']
    flag10 = data['flag10']
    if ave5 > ave10:
        print('最近为偏上升形态')
    else:
        print('最近为偏下降形态')
    # (1) 突破十日线 and macd形态多头 全仓买入
    if flag10 == 1 and max > ave10 and (macd == '/' or macd == 'v'):
        print(name + '全仓买入')
        deal_flag = 1
        deal_price = ave10
        if min > ave10:
            print('高开高走')
            deal_price = kp
        data['flag5'] = -1  # 变更5日flag
        data['flag10'] = -1  # 变更10日flag
    # (2) 跌破十日线 and macd形态空头 清仓卖出
    elif flag10 == -1 and min < ave10 and (macd == '\\' or macd == '^'):
        print(name + '清仓卖出')
        deal_flag = 3
        deal_price = ave10
        if max < ave10:
            print('低开低走')
            deal_price = kp
        data['flag5'] = 1  # 变更5日flag
        data['flag10'] = 1  # 变更10日flag
    # (3) 突破5日均线,未突破10日均线,macd多头形态 半仓买入
    elif flag5 == 1 and max > ave5 and (macd == '/' or macd == 'v'):
        print(name + "五日均线价格半仓买入")
        deal_flag = 2
        deal_price = ave5
        if min > ave5:
            print(name + '高开高走')
            deal_price = kp
        data['flag5'] = -1  # 监控跌破
        data['flag10'] = 1  # 监控突破
    # (4) 跌破5日均线,未跌破10日线,macd空头形态 减半仓
    elif flag5 == -1 and min < ave5 and (macd == '\\' or macd == '^'):
        print(name + "五日均线价格减半仓")
        deal_flag = 4
        deal_price = ave5
        if max < ave5:
            print(name + '低开低走')
            deal_price = kp
        data['flag5'] = 1  # 监控突破
        data['flag10'] = -1  # 监控跌破
    else:
        print(data)
        return data
    # 交易价格 deal_price
    # 交易标志 deal_flag = 0  # 1:全仓 2:加半仓 3:清仓 4:减半仓
    data['deal_price'] = deal_price
    data['deal_flag'] = deal_flag
    return deal_complete(data)


if __name__ == '__main__':
    stock_list = [
        # {'code': '600660', 'name': '福耀玻璃'},
        # {'code': '600859', 'name': '王府井'},
        # {'name': '中远海控', 'code': '601919', 'exchange': '1'},
        {'code': '601318', 'name': '中国平安'}
    ]
    monitor_up_down(stock_list, 60)
